#ifndef prs_FrmBuildStyle_H
#define prs_FrmBuildStyle_H

#include "prs_FrmPanelStyle.h"
#include "prs_FrmStringStyle.h"
#include "prs_FrmIntegerStyle.h"
#include "prs_FrmDoubleStyle.h"
#include "prs_FrmDateStyle.h"
#include "prs_FrmButtonStyle.h"
#include "prs_FrmLineStyle.h"
#include "prs_FrmParaStyle.h"
#include "prs_FrmParaEditStyle.h"
#include "prs_FrmColStyle.h"
#include "prs_FrmRowStyle.h"
#include "prs_FrmSplitterStyle.h"
#include "prs_FrmScrollBarStyle.h"
#include "prs_FrmPageControlStyle.h"
#include "prs_FrmTableStyle.h"
#include "prs_FrmImageStyle.h"
#include "prs_Root.h"

namespace prs {

///////////////////////////////////////////////////////////////////////////////

struct TFrmBuildStyle
  :public svl::IVisitor<TNodeRoot>
  ,public svl::IVisitor<TNodeUnit>
  ,public svl::IVisitor<TNodeStyle>
  ,public svl::IVisitor<TNodeFrmPanelStyle>
  ,public svl::IVisitor<TNodeFrmStringStyle>
  ,public svl::IVisitor<TNodeFrmIntegerStyle>
  ,public svl::IVisitor<TNodeFrmDoubleStyle>
  ,public svl::IVisitor<TNodeFrmDateStyle>
  ,public svl::IVisitor<TNodeFrmButtonStyle>
  ,public svl::IVisitor<TNodeFrmLineStyle>
  ,public svl::IVisitor<TNodeFrmParaStyle>
  ,public svl::IVisitor<TNodeFrmParaEditStyle>
  ,public svl::IVisitor<TNodeFrmColStyle>
  ,public svl::IVisitor<TNodeFrmRowStyle>
  ,public svl::IVisitor<TNodeFrmRowExpandStyle>
  ,public svl::IVisitor<TNodeFrmVSplitterStyle>
  ,public svl::IVisitor<TNodeFrmHSplitterStyle>
  ,public svl::IVisitor<TNodeFrmVScrollBarStyle>
  ,public svl::IVisitor<TNodeFrmHScrollBarStyle>
  ,public svl::IVisitor<TNodeFrmPageControlStyle>
  ,public svl::IVisitor<TNodeFrmTableStyle>
  ,public svl::IVisitor<TNodeFrmImageStyle>
{
  TFrmBuildStyle()                     { parentStyle = NULL;}
  TFrmBuildStyle(TFrmBuildStyle &From) { *this = From;}
  //
  void Visit(TNodeRoot  &Node);
  void Visit(TNodeUnit  &Node);
  void Visit(TNodeStyle &Node);
  //
  void Visit(TNodeFrmPanelStyle    &Node) { SetStyle(Node);}
  void Visit(TNodeFrmStringStyle   &Node) { SetStyle(Node);}
  void Visit(TNodeFrmIntegerStyle  &Node) { SetStyle(Node);}
  void Visit(TNodeFrmDoubleStyle   &Node) { SetStyle(Node);}
  void Visit(TNodeFrmDateStyle     &Node) { SetStyle(Node);}
  void Visit(TNodeFrmButtonStyle   &Node) { SetStyle(Node);}
  void Visit(TNodeFrmLineStyle     &Node) { SetStyle(Node);}
  void Visit(TNodeFrmParaStyle     &Node) { SetStyle(Node);}
  void Visit(TNodeFrmParaEditStyle &Node) { SetStyle(Node);}
  void Visit(TNodeFrmColStyle      &Node) { SetStyle(Node);}
  void Visit(TNodeFrmImageStyle    &Node) { SetStyle(Node);}
  //
  void Visit(TNodeFrmRowStyle       &Node) { SetStyle(Node);}
  void Visit(TNodeFrmRowExpandStyle &Node) { SetStyle(Node);}
  //
  void Visit(TNodeFrmTableStyle &Node) { SetStyle(Node);}
  //
  void Visit(TNodeFrmVSplitterStyle &Node) { SetStyle(Node);}
  void Visit(TNodeFrmHSplitterStyle &Node) { SetStyle(Node);}
  //
  void Visit(TNodeFrmVScrollBarStyle &Node) { SetStyle(Node);}
  void Visit(TNodeFrmHScrollBarStyle &Node) { SetStyle(Node);}
  //
  void Visit(TNodeFrmPageControlStyle &Node) { SetStyle(Node);}
  //
  template<class TNodeFrm___Style> void SetStyle(TNodeFrm___Style &Node)
  {
    TNodeFrm___Style *ParentStyleControl = NULL;
    
    if (parentStyle) {
      ParentStyleControl = dynamic_cast<TNodeFrm___Style*>(
        parentStyle->SearchStyleControlByType( Node.GetNodeType() )
      );
    }
    
    if (ParentStyleControl) {
      Node.Style.Value.SetFromParent(&ParentStyleControl->Style.Value);
    }
    else {
      Node.Style.Value.SetFromParent(NULL);
    }
  }
  
private:  
  TNodeStyle *parentStyle;
};

///////////////////////////////////////////////////////////////////////////////
}

#endif
